<?php
/**
 * 系统菜单
 *
 */
class Menu extends MyBase{
	private $menus = array();

	function __construct() {
		parent::__construct('menu.id', array('keyword' => 'title'));
	}
	
	/**
	 * 修改系统菜单
	 *
	 * @param int		$id
	 * @param array		$post
	 * @return int
	 */
	public function edit($post){
		$id = empty($post['id']) ? 0 : intval($post['id']);
		$select = array('name' => $post['name']);
		if($id > 0){
			$select['kept'] = " AND id!={$id}";
		}
		$rs = $this->db->get_row($this->tbname, $select, 'id');
		if(!empty($rs)) {return lang('already').lang('exist');}
		
		$powers = $this->formatPower_in($post['power']);
		/*$power_exists = $this->power_exists(array_keys($power), $id);
		if(!empty($power_exists)){
			return -3;	// 权限已经存在
		}*/
		
		$data = array(
			'pid'		=> $post['pid'],
			'name'		=> $post['name'],
			'path'		=> $post['path'], 
			'power'		=> serialize($powers), 
			'target'	=> $post['target'],
			'rank'		=> $post['rank'],
			'memo'		=> $post['memo'],
		);
		if($id > 0){
			$data['updatetime'] = TIME;
			$r = $this->db->update($this->tbname, array('id' => $id), $data);
		}else{
			$data['addtime'] = TIME;
			$r = $id = $this->db->insert($this->tbname, $data);
		}
		
		if($r > 0){
			$this->update_langs($id, $post['path'], $post['name'], $powers);	// 更新语言
			return $this->cache_menu();	// 更新缓存
		}
		return $r;
	}
	
	/**
	 * 更新排序
	 */
	public function rank($post){
		if(!is_array($post['rank']))$post['rank'] = array($post['rank']);
		$iRtn = 0;
		$t = TIME;
		foreach($post['rank'] as $id => $rank){
			$data = array(
				'rank'		=> intval($rank), 
				'updatetime'=> $t,
			);
			if($this->db->update($this->tbname, array('id' => $id), $data)){
				$iRtn ++;
			}
		}
		if($iRtn > 0){
			return $this->cache_menu();
		}
		return $iRtn;
	}
	
	/**
	 * 更新代理，即菜单在角色转换后是否可用
	 */
	public function agency($post){
		if(!is_array($post['agency']))$post['agency'] = array($post['agency']);
		$iRtn = 0;
		foreach($post['agency'] as $id => $agency){
			$data = array(
				'agency'		=> intval($agency), 
				'updatetime'	=> TIME 
			);
			if($this->db->update($this->tbname, array('id' => $id), $data)){
				$iRtn ++;
			}
		}
		if($iRtn > 0){
			return $this->cache_menu();
		}
		return $iRtn;
	}
	
		
	/**
	 * 删除系统菜单
	 */
	public function del($post){
		if(!is_array($post['list'])) {
			$post['list'] = array($post['list']);
		}
		$iRtn = 0;
		foreach($post['list'] as $id){
			$sublist = $this->get_menu_list($id);
			
			if(!empty($sublist))continue;
			unset($this->menus);
			if($this->db->delete($this->tbname, array('id' => $id))){
				$iRtn ++;
			}
		}
		if($iRtn > 0){
			return $this->cache_menu();
		}
		return $iRtn;
	}
	
	/**
	 * 取一条记录
	 *
	 * @param int			$id
	 * @param string		$fields
	 * @return array
	 */
	/*public function get_row($id, $fields = '*'){
		$select = array('id' => $id);
		return $this->db->get_row($this->tbname, $select, $fields);
	}*/
	
	/**
	 * 取列表
	 *
	 * @param string		$fields
	 * @param array			$select
	 * @param int			$page
	 * @param int			$size
	 * @return array
	 */
	/*public function get_list($fields = '*', $select = array(), $order = array(), $page = 1, $size = 10, $offset = PAGE_OFFSET){
		if(!empty($select['keyword'])){
			$select['kept'] = " AND `title` LIKE '%{$select['keyword']}%'";
		}
		return $this->db->get_list($this->tbname, $fields, $select, $order, $page, $size, $offset);
	}*/
	
	/********************************************************************************
	 * 取菜单树
	 ********************************************************************************/
	
	public function get_menu_list($pid = 0, $keyword = '', $level = 0, $depth = 0){
		$where = empty($keyword) ? '' : "AND name LIKE '%$keyword%'";
		$sql = "SELECT * from `{$this->tbname}` WHERE pid=$pid $where order by rank DESC,id ASC";
		$list = $this->db->sql_all($sql);
		if(isset($list['list']) && !empty($list['list'])){
			foreach($list['list'] as $row){
				$row['level'] = $level;
				$this->menus[] = $row;
				$next_level = $level + 1;
				if(empty($depth) || $next_level < $depth){
					$this->get_menu_list($row['id'], $keyword, $next_level, $depth);
				}
			}
		}
		return $this->menus;
	}
	
	public function get_menu_tree_ul($pid = 0, $keyword = '', $except_id = 0, $level = 99){
		$menus = array();
		if($pid == 0){
			$menus[] = '<li><a href="#" onClick="set_parent_menu(this, 0);return false;">'.lang('root').'</a><ul>';
		}
		$where = (empty($except_id) ? '' : " AND id<>$except_id").(empty($keyword) ? '' : " AND name LIKE '%$keyword%'");
		$sql = "SELECT * from `{$this->tbname}` WHERE pid=$pid $where order by rank DESC,id ASC";
		$list = $this->db->sql_all($sql);
		if(isset($list['list']) && !empty($list['list'])){
			foreach($list['list'] as $row){
				$sub_menus = $this->get_menu_tree_ul($row['id'], $keyword, $except_id, $level + 1);
				if(!empty($sub_menus)){
					$menus[] = '<li><a href="#" onClick="set_parent_menu(this,'.$row['id'].');return false;">'.lang($row['name']).'</a>';
					
					$menus[] = '<ul>';
					// $menus[] = '<li class="topline"></li>';
					$menus[] = $sub_menus;
					$menus[] = '</ul></li>';
				}else{
					$menus[] = '<li><a href="#" onClick="set_parent_menu(this,'.$row['id'].');return false;">'.lang($row['name']).'</a></li>';
				}
				
			}
		}
		
		if($pid == 0){
			$menus[] = '</ul></li>';
		}
		return implode("\n", $menus);
	}
	
	public function get_menu_tree($pid = 0, $keyword = '', $except_id = 0, $level = 0){
		$menus = array();
		$where = (empty($except_id) ? '' : " AND id<>$except_id").(empty($keyword) ? '' : " AND name LIKE '%$keyword%'");
		$sql = "SELECT * from `{$this->tbname}` WHERE pid=$pid $where order by rank DESC,id ASC";
		//echo $sql."<br />\n";
		$list = $this->db->sql_all($sql);
		if(isset($list['list']) && !empty($list['list'])){
			foreach($list['list'] as $row){
				$row['level'] = $level;
				$sub_menus = $this->get_menu_tree($row['id'], $keyword, $except_id, $level + 1);
				if(!empty($sub_menus)){
					$row['menus'] = $sub_menus;
				}
				$menus[] = $row;			
			}
		}
		return $menus;
	}
	
	/********************************************************************************
	 * 格式化
	 ********************************************************************************/
	
	// 入库前将权限格式化为序列串
	public function formatPower_in($power){
		$power_arr = array();
		$power = trim($power);
		if(!empty($power)){
			$power = str_replace('：', ':', $power);		// 避免中文冒号造成错误
			$power = str_replace('；', ';', $power);		// 避免中文分号造成错误
			$power = str_replace("\n", ';', $power);
			$row_arr = explode(";", $power);
			foreach($row_arr as $row){
				$tmp_arr = explode(':', $row);
				if(!empty($tmp_arr[1])){
					$power_arr[$tmp_arr[0]] = $tmp_arr[1];
				}
			}
		}
		return $power_arr;
	}
	
	// 出库后将权限反序列化为编辑所需格式
	public function formatPower_out($powers, $replace = false){
		if(empty($powers))return false;
		
		global $__l;	// 语言包
		$power_arr = array();
		$powers = @unserialize($powers);
		if(!empty($powers)){
			foreach($powers as $key => $power){
				if($replace)$power = lang($power);
				$power_arr[] = "{$key}:{$power}";
			}
		}
		return implode(";", $power_arr);
	}
	
	// 判断权限是否已经存在
	private function power_exists($power, $menu_id = 0){
		$menus = @cache_read('menus.php');
		$menu_list = $menus['menu_list'];
		$powers = array();
		foreach($menu_list as $row){
			if(!empty($menu_id) && $row['id'] == $menu_id){
				continue;	// 跳过本菜单
			}
			$_powers = unserialize($row['power']);
			if(!empty($_powers)){
				foreach($_powers as $_power => $title){
					$powers[] = $_power;
				}
			}
		}
		return array_uintersect($power, $powers, "strcmp");
	}
	
	public function update_langs($menu_id, $path, $name, $powers){
		$langs = cache_read('langs.php');
		$librarys = cache_read('librarys.php');

		$lang_id = $langs['lang_mark_list']['zh-cn']['id'];
		$library_id = $librarys['library_mark_list']['menu'];

		//$del_arr = array('列表', '添加');
		$oSentence = new Sentence();
		
		$update = array();
		if(empty($path)){
			$mark =  "_mm_{$menu_id}";
		}else{
			if(strpos($path, './app/') !== false){
				$path = array_pop(explode('/', $path));
				$mark = '_mm_'.trim(array_shift(explode('.', $path)));
			}else{
				$path = array_pop(explode('?', $path));
				parse_str($path, $arr);
				if(!isset($arr['mdl']) || !isset($arr['do'])){
					return false;
				}
				$mark = '_mm_'.trim($arr['frm']).'_'.trim($arr['mdl']).'_'.trim($arr['do']);
			}
		}
		$update['name'] = $mark;
		// 组
		/*$data = array(
			'langid'	=> $lang_id,
			'libraryid'	=> $library_id,
			'mark'		=> array_shift(explode('_', $mark)),
			'content'	=> str_replace($del_arr, '', $name),
			'state'		=> 1,
		);
		$sentence_id = $oSentence->edit($data);*/
		// 菜单项
		$data = array(
			'langid'	=> $lang_id,
			'libraryid'	=> $library_id,
			'mark'		=> $mark,
			'content'	=> $name,
			'state'		=> 1,
		);
		$sentence_id = $oSentence->edit($data, true);
		// 处理权限
		if(!empty($powers)){
			foreach($powers as $power => $content){
				$mark = '_mp_'.$arr['frm'].'_'.$power;
				$data = array(
					'langid'	=> $lang_id,
					'libraryid'	=> $library_id,
					'mark'		=> $mark,
					'content'	=> $content,
					'state'		=> 1,
					'addtime'	=> TIME,
				);
				$sentence_id = $oSentence->edit($data, true);
				$powers[$power] = $mark;
			}
		}
		// 更新菜单文件
		$oSentence->export_menu_sentences();
		$update['power'] = serialize($powers);
		return $this->db->update($this->tbname, array('id' => $menu_id), $update);
	}
	
	/********************************************************************************
	 * 缓存
	 ********************************************************************************/
	
	public function cache_menu(){
		$menu_list = $this->get_menu_list();
		$menu_tree = $this->get_menu_tree();
		$titles = array();
		foreach($menu_list as $row){
			$powers = unserialize($row['power']);
			if(!empty($powers)){
				foreach($powers as $power => $title){
					$titles[$power] = $title;
				}
			}
		}
		
		//$r1 = cache_write('titles.php', $titles);
		$r2 = cache_write('menus.php', array('menu_list' => $menu_list, 'menu_tree' => $menu_tree));

		if(/*$r1 > 0 && */$r2 > 0){
			return 1;
		}else{
			return -1;
		}
	}
	
	/********************************************************************************
	 * 遍历
	 ********************************************************************************/
	
	public function treval_menu($menu_tree, $powers){
		if(!isset(Statics::$access_arr) || !is_array(Statics::$access_arr)){
			die('缺少配置文件');
		}
		$_tmp_access = @array_keys(Statics::$access_arr);
		
		$menu_arr = array();
		foreach($menu_tree as $menu){
			if(in_array($menu['id'], $powers)){
				if(isset($menu['menus']) && is_array($menu['menus'])){
					if(!in_array($menu['path'], $_tmp_access)){
						$menu['path'] = '#';
					}
					$menu['menus'] = $this->treval_menu($menu['menus'], $powers);
				}
				$menu_arr[] = $menu;
			}
		}
		return $menu_arr;
	}
	
	// 将树状结构转换成列表结构
	public function menu_tree_to_list($tree, $level = 0){
		$menus = array();
		if(is_array($tree)){
			foreach($tree as $menu){
				$menu['level'] = $level;
				$submenu_tree = isset($menu['menus']) ? $menu['menus'] : array();
				unset($menu['menus']);
				$menus[] = $menu;
				if(!empty($submenu_tree)){
					$submenus = $this->menu_tree_to_list($submenu_tree, $level + 1);
					$menus = array_merge($menus, $submenus);
				}
			}
		}
		return $menus;
	}
}
?>